#include <stdio.h>
#include "Thread_Pool.h"
#include <stdlib.h>
#include "Thread_Pool_Manager.h"
#include "Thread_Pool_Worker.h"
#include "Thread_Pool_Manager.h"


Thread_Poolp ThreadPool_Init(u16 max_task, u16 max_thread, u16 min_thread)
{
    int ret = 0;
    int i = 0;
    
    //0. 创建线程池
    Thread_Poolp poolp = (Thread_Pool *)calloc(1, sizeof(Thread_Pool));
    if(poolp == NULL)
    {
        perror("pool create failed!");
        goto FAILED;
    }
   
    //1. 由指定的大小，创建任务队列
    poolp->tasks = (Task *)calloc(max_task, sizeof(Task));
    if(poolp->tasks == NULL)
    {
        perror("calloc failed");
        goto FAILED;
    }
    //1+. 关于任务队列的数据
    poolp->q_front = 0;
    poolp->q_rear = 0;
    poolp->task_num = 0;
    poolp->max_task = max_task;
    
    //2. 由指定的大小，创建核心线程号数组
    poolp->threads = (pthread_t *)calloc(max_thread, sizeof(pthread_t));
    if(poolp->threads == NULL)
    {
        perror("calloc failed");
        goto FAILED;
    }
    //2+. 将数据(用户指定的)存储进线程池中
    poolp->max_thrd = max_thread;
    poolp->min_thrd = min_thread;

    //3. 创建 min_thread 个核心线程
    for(i=0; i<min_thread; i++)
    {
        ret = pthread_create(&(poolp->threads[i]), NULL, ThreadPool_Worker, poolp);
        if(ret < 0)
        {
            perror("core thread create failed!");
            goto FAILED;
        }
    }

    //3. 创建管理者线程
    ret = pthread_create(&poolp->manager, NULL, ThreadPool_ManagerFunc, poolp);
    if(ret < 0)
    {
        perror("manager thread create failed!");
        goto FAILED;
    }
    //3+. 其他相关数据(多数用于管理者)
    poolp->live_thrd_num = min_thread;
    poolp->busy_thrd_num = 0;
    poolp->waitexit_thrd_num = 0;
    poolp->shutdown = 0;

    //4. 初始化相应的锁、条件变量
    if( (pthread_mutex_init(&poolp->pool_mutex, NULL)!=0)||
        (pthread_cond_init(&poolp->pool_cond_notemp, NULL)!=0)||
        (pthread_cond_init(&poolp->pool_cond_notfull, NULL)!=0)||
        (pthread_mutex_init(&poolp->busy_mutex, NULL)!= 0) 
      )
    {
        perror("mutex or cond init failed!");
        goto FAILED;
    }

    return poolp; 
    FAILED: //或者使用 do while(0) 和 break 组合:
    {
        if(poolp->tasks == NULL)    free(poolp->tasks);
        if(poolp->threads == NULL)  free(poolp->threads);
        if(poolp == NULL)   free(poolp);
        return NULL;
    }
}


void ThreadPool_Destroy(Thread_Poolp poolp)
{
    int i = 0;

    if(poolp == NULL)
    {
        return;
    }
    //0. 等待任务完成退出(注意)
    poolp->shutdown = 1;
    pthread_join(poolp->manager, NULL);//manager退出
    printf("Manager Died\n");
    #if 0
    for(i=0; i<poolp->max_thrd; i++)    //worker退出
    {
        printf("pthread [%d] is trying exiting\n", i);
        if((poolp->threads[i] != 0)&&(ThreadLive_Detec(poolp->threads[i])))
        {
            pthread_cond_signal(&poolp->pool_cond_notemp);
            pthread_join(poolp->threads[i], NULL);
            printf("pthread [%d] is exited\n", i);
        }
    }
    #endif
    printf("live thrd:%d\n", poolp->live_thrd_num);
    for(i=0; i<poolp->live_thrd_num; i++)    //worker退出
    {
        pthread_cond_broadcast(&poolp->pool_cond_notemp);
        printf("WHY why why\n");
        //pthread_join(poolp->threads[i], NULL);
    }
#if 0
    for(i=0; i<poolp->max_thrd; i++)    //worker退出
    {
        if(poolp->threads[i]!=0 && ThreadLive_Detec(poolp->threads[i]))//当线程被创建的时候，总是按照选择最低的序号；但是退出的时候， 并不一定按照最低的序号,因此上面的循环为max
        {
            pthread_join(poolp->threads[i], NULL);
            printf("pthread [%d] has exited\n", i);
        }
    }
#endif
    //1. 销毁条件变量和互斥锁(注意)
#if 0 // 未知原因的阻塞？
    pthread_cond_destroy(&poolp->pool_cond_notemp);
    pthread_cond_destroy(&poolp->pool_cond_notfull);
    pthread_mutex_destroy(&poolp->pool_mutex);
    pthread_mutex_destroy(&poolp->busy_mutex);
#else
    pthread_mutex_destroy(&poolp->pool_mutex);
    pthread_mutex_destroy(&poolp->busy_mutex);
    pthread_cond_destroy(&poolp->pool_cond_notemp);
    pthread_cond_destroy(&poolp->pool_cond_notfull);
#endif
 
    //2. 释放堆内存（free(NULL) 是安全的）
    free(poolp->tasks);
    free(poolp->threads);
    free(poolp);

}